package com.appspot.codelab.docs.server;

import java.util.Date;
import java.util.List;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

/**
 * Models and stores a User Project.
 */
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class UserProject {

    @SuppressWarnings("unused")
	@PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;
    
    @Persistent
    private String project;

    @Persistent
    private String email;
    
    @Persistent
    private String token;

    @Persistent
    private Date obtained;

    @Persistent
    private Date activity;

    /**
     * Constructs a new User Project.
     * 
     * @param project the project name
     * @param email the user's email
     * @param token the project token
     * @param obtained the date the entry was created
     * @param obtained the date the entry was last used
     */
    private UserProject(String project, String email, String token, Date obtained, Date activity) {
      this.project = project;
      this.email = email;
      this.token = token;
      this.obtained = obtained;
      this.activity = activity;
    }

    /**
     * Retrieves the project name.
     * 
     * @return the project name
     */
    public String getProject() {
        return project;
    }

    /**
     * Retrieves the user email.
     * 
     * @return the user email
     */
    public String getEmail() {
        return email;
    }

    /**
     * Retrieves the project token.
     * 
     * @return the project token
     */
    public String getToken() {
        return token;
    }
    
    /**
     * Retrieves the date the entry was created.
     * 
     * @return the date the entry was created
     */
    public Date getObtained() {
      return obtained;
    }
    
    /**
     * Retrieves the date the entry was last used.
     * 
     * @return the date the entry was last used
     */
    public Date getActivity() {
      return activity;
    }
    
    /**
     * Sets the entry's last activity date.
     * 
     * @param activity the entry's last activity
     */
    public void setActivity(Date activity) {
      this.activity = activity;
      PersistenceManager pm = PMF.get().getPersistenceManager();
      try {
    	pm.makePersistent(this);
      } catch (JDOObjectNotFoundException e) {
      } finally {
        pm.close();
      }
    }
    
    /**
     * Sets the project token.
     * 
     * @param token the project token
     */
    private void setToken(String token) {
      this.token = token;
      this.obtained = new Date();
    }
    
    /**
     * Retrieves the project entry for a given user, by email.
     * 
     * @param project the project name
     * @param email the user's email address
     * @return the User Project, if any
     */
    public static UserProject getUserProject(String project, String email) {
      PersistenceManager pm = PMF.get().getPersistenceManager();
      UserProject proj = null;
      try {
    	proj = getUserProject(pm, project, email);
      } catch (JDOObjectNotFoundException e) { }
      finally {
        pm.close();
      }
      return proj;
    }
    
    /**
     * Stores a user project. If a project already exists for the specified
     * user, it's value is updated.
     * 
     * @param project the project name
     * @param email the user's email address
     * @param token the project token
     * @return the new or updated User Project
     */
    public static UserProject storeUserProject(String project, String email, String token) {
      PersistenceManager pm = PMF.get().getPersistenceManager();
      UserProject at = null;
      try {
        at = getUserProject(pm, project, email);
        if (at == null) {
          at = new UserProject(project, email, token, new Date(), new Date());
        }
        at.setToken(token);
        pm.makePersistent(at);
      } finally {
        pm.close();
      }
      return at;
    }
    
    /**
     * Clears a user's projects from the data store.
     * 
     * @param email the user's email address
     */
    @SuppressWarnings("unchecked")
	public static void clearUserProjects(String email) {
      PersistenceManager pm = PMF.get().getPersistenceManager();
      Query query = pm.newQuery(UserProject.class);
      query.setFilter("email == emailParam");
      query.declareParameters("String emailParam");
      try {
          List<UserProject> results = (List<UserProject>) query.execute(email);
          if (results.iterator().hasNext()) {
            for (UserProject proj : results) {
              pm.deletePersistent(proj);
            }
          }
      } finally {
          query.closeAll();
      }
    }
    
    @SuppressWarnings("unchecked")
	protected static UserProject getUserProject(
          PersistenceManager pm, String project, String email) {
      Query query = pm.newQuery(UserProject.class);
      query.setFilter("email == emailParam && project == projParam");
      query.declareParameters("String emailParam, String projParam");
      try {
        List<UserProject> results = (List<UserProject>) query.execute(email, project);
        if (results.iterator().hasNext()) {
          for (UserProject proj : results) {
            return proj;
          }
        }
      } finally {
        query.closeAll();
      }
      return null;
    }
}